
#include "StdAfx.h"
#include "LinkCtrl.h"
#include "CommonFun.h"
#include "../Res/resource.h"
#include "LinkComboBox.h"

CLinkCtrl::CLinkCtrl(INPUT_FIELD_INFO* pFieldInfo)
{
	m_hOldWindowProc		= NULL;
	m_pInputFieldInfo		= pFieldInfo;
}

CLinkCtrl::~CLinkCtrl()
{
}

void CLinkCtrl::EnableCustMsgProc(BOOL bCustProc)
{
	if(m_pInputFieldInfo)
		m_pInputFieldInfo->bCustMsgProc = bCustProc;
}

LRESULT CALLBACK CLinkCtrl::MainWindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	CLinkCtrl* pThis= (CLinkCtrl*)::GetWindowLong(hWnd, GWL_USERDATA);
	if(pThis && (!pThis->m_pInputFieldInfo || !pThis->m_pInputFieldInfo->bCustMsgProc))
	{
		WNDPROC oldProc = pThis->GetPrevWndProc();
		if(oldProc)
			return oldProc(hWnd, message, wParam, lParam);

		return 0;
	}
	
	switch(message) 
	{
	case WM_KILLFOCUS:
		if(pThis)
		{
			HWND hNextWnd = (HWND)wParam;
			if(hNextWnd)
			{
				TCHAR szClassName[MAX_PATH] = {0};
				::GetClassName(hNextWnd, szClassName, MAX_PATH);
				if(_tcsicmp(szClassName, _T("Button")) == 0)
					break;
			}
	
			BOOL bValid = FALSE;
			if(pThis->m_pInputFieldInfo && pThis->m_pInputFieldInfo->KillFocusCheckFunc && pThis->m_pInputFieldInfo->pLinkCtrl)
			{
				pThis->m_pInputFieldInfo->KillFocusCheckFunc(pThis->m_pInputFieldInfo);
			}
			else
			{
				bValid = pThis->CheckDataValidFirst();
				if(bValid)
					bValid = pThis->CheckCtrlDataValid();
			}

			pThis->m_strBeforeValue.Empty();
		}
		break;

	case WM_SETFOCUS:
		if(pThis)
		{
			pThis->m_strBeforeValue = pThis->GetControlData();
			pThis->ScrollToVisible();
		}
		break;
		
	case WM_COMMAND:
		if(pThis)
		{
			if(pThis->m_pInputFieldInfo && pThis->m_pInputFieldInfo->pLinkCtrl && pThis->m_pInputFieldInfo->dwCtrlType == IBT_ComboBox)
			{
				if(HIWORD(wParam) == CBN_SELCHANGE)
				{
					if(pThis->m_pInputFieldInfo->FieldCheckFunc)
						pThis->m_pInputFieldInfo->FieldCheckFunc(pThis->m_pInputFieldInfo);
				}
			}
		}
		break;

	default:
		 break;
	}

	if(pThis)
	{
		WNDPROC oldProc = pThis->GetPrevWndProc();
		if(oldProc)
			return oldProc(hWnd, message, wParam, lParam);
	}

	return 0;
}

BOOL CLinkCtrl::PreTranslateMessage(MSG* pMsg, LPVOID pThis)
{
	if(!m_pInputFieldInfo || !m_pInputFieldInfo->bCustMsgProc)
		return FALSE;

	switch(pMsg->message)
	{
	case WM_KEYDOWN:
		{
			if(pMsg->wParam == VK_RETURN)
			{
				BOOL bValid = FALSE;
				if(m_pInputFieldInfo && m_pInputFieldInfo->FieldCheckFunc && m_pInputFieldInfo->pLinkCtrl)
				{
					bValid = m_pInputFieldInfo->FieldCheckFunc(m_pInputFieldInfo);
				}
				else
				{
					bValid = CheckDataValidFirst();
					if(bValid)
						bValid = CheckCtrlDataValid();
				}
				
				if(bValid)
					pMsg->wParam = VK_TAB;
			}
			else
			{
				return OnCtrlKeyDown(pMsg->wParam);
			}
		}
		break;

	case WM_MOUSEWHEEL:
		{
			if(m_pInputFieldInfo && m_pInputFieldInfo->pLinkCtrl && m_pInputFieldInfo->dwCtrlType == IBT_ComboBox)
			{
				CLinkComboBox* pCombo = (CLinkComboBox*)m_pInputFieldInfo->pLinkCtrl;
				CWnd* pParent = pCombo->GetParent();
				if(pParent)
				{
					HWND hWndParent = pParent->GetSafeHwnd();
					if(hWndParent)
					{
						::SendMessage(hWndParent, pMsg->message, pMsg->wParam, pMsg->lParam);
						return TRUE; // NOT to process any more
					}
				}
			}
		}
		break;

	default:
		break;
	}
	
	return FALSE;	//MSDN: Nonzero if the message was translated and should not be dispatched; 0 if the message was not translated and should be dispatched.
}

void CLinkCtrl::PreSubclassWindow(LPVOID pThis)
{
	if(pThis)
	{
		CWnd* pWnd = (CWnd*)pThis;
		//  Set max text length
		if(GetControlType() == IBT_EditBox || GetControlType() == IBT_EditDate)
		{
			if(m_pInputFieldInfo)
			{
				CEdit* pEdit = (CEdit*)pWnd;
				pEdit->SetLimitText(m_pInputFieldInfo->nMaxLength);
			}
		}

		//  Subclass Edit
		HWND hWnd = pWnd->GetSafeHwnd();
		if(hWnd)
		{
			::SetWindowLong(hWnd, GWL_USERDATA, (LONG)this);
			m_hOldWindowProc = (WNDPROC)::SetWindowLong(hWnd, GWL_WNDPROC, (LONG)MainWindowProc);
		}
	}
}

BOOL CLinkCtrl::CheckDataValidFirst()
{
	CString strText = GetControlData();

	strText.TrimLeft();
	strText.TrimRight();

	BOOL bIsReadOnly = FALSE;
	if(GetControlType() == IBT_EditBox)
	{
		CEdit* pEdit = (CEdit*)m_pInputFieldInfo->pLinkCtrl;
		DWORD dwStyle = pEdit->GetStyle();
		if(dwStyle & ES_READONLY)
			bIsReadOnly = TRUE;
	}

	if(m_pInputFieldInfo && !m_pInputFieldInfo->bAllowEmpty && strText.IsEmpty() && !bIsReadOnly)
	{
		if(m_pInputFieldInfo->dwFieldDescStringID > 0)
		{
			CString strFieldDesc = GetResString(m_pInputFieldInfo->dwFieldDescStringID);
			CString strNotAllowEmpty = GetResString(IDS_PAT_NOT_ALLOW_EMPTY);

			GYMsgBox(strFieldDesc + strNotAllowEmpty, MB_ICONINFORMATION|MB_OK);
		}
		else
		{
			GYMsgBox(IDS_PAT_STRING_EMPTY, MB_ICONINFORMATION|MB_OK);
		}

		return FALSE;
	}

	return TRUE;
}


CString CLinkCtrl::GetCtrlFieldName()
{
	if(m_pInputFieldInfo)
		return m_pInputFieldInfo->szFieldName;
	
	return _T("");
}

CString	CLinkCtrl::GetCtrlFieldValue()
{
	if(m_pInputFieldInfo)
	{
		CString strValue = GetControlData();

		switch(m_pInputFieldInfo->dwFieldType)
		{
		case ftString:
			strValue = _T("'") + strValue + _T("'");
			return strValue;

		case ftNumber:
			if(strValue.IsEmpty())
				strValue = _T("0");
			return strValue;

		case ftDate:
			strValue = _T("'") + strValue + _T("'");
			return strValue;
		}
	}
	
	return _T("''");
}
